﻿import $ from 'jquery';
import { Extractor, ExtractResult } from "@/core/ruiji/extractor";
import { db } from "@/core/ruiji/db";
import { InlineDiff } from '@/core/diff/inline';
import { _browser } from '@/core/utils';

class AutoPaging {
    timer: number = 0;
    rule!: any;
    currentPage: number = 0;
    totalPage: number = 0;
    url: string = "";
    extractor: Extractor = new Extractor();
    results: Map<string, ExtractResult> = new Map();
    pages: string[] = [];
    interval: number = 10;
    tab!: chrome.tabs.Tab;
    tabId: number | undefined = -1;
    win: Window | null = null;
    funcs: any[] = [];

    constructor() {

    }

    start(url: string, rule: any, funcs: any[], interval: number, pages: number) {
        clearInterval(this.timer);
        this.timer = 0;

        this.rule = rule;
        this.currentPage = pages;
        this.totalPage = pages;
        this.results.clear();
        this.url = url;
        this.interval = interval;
        this.funcs = funcs;
        this.extractor.setFuncs(funcs);
    }

    excute(url: string, result: ExtractResult): any {
        this.currentPage--;
        this.results.set(url, result);

        let pages = result.paging || [];
        pages = Array.from(new Set(pages.map(page => {
            if (!page.startsWith("http")) {
                return new URL(url).origin + page;
            }

            return page;
        })));

        if (this.currentPage <= 0 || pages.length === 0) {
            this.stop();
            return null;
        } else {
            var d = new InlineDiff();
            var model = d.buildDiffModel(this.pages.join("\n"), pages.join("\n"));

            this.pages = Array.from(new Set(model.lines.map(l => { return l.text; })));

            let find = this.pages.some(page => {
                if (this.results.has(page))
                    return false;

                url = page;
                return true;
            });

            if (!find) {
                this.stop();
                return null;
            }

            return {
                url: url,
                interval: this.interval,
                current: this.currentPage,
                total: this.totalPage
            };
        }
    }

    stop() {
        clearInterval(this.timer);

        if (this.results.size > 0) {
            if (this.rule.hub) {
                let resolves: any[] = [];

                this.results.forEach(result => {
                    if (result.tiles) {
                        result.tiles.forEach((r: any) => {
                            resolves.push(db.article.update(r.metas, this.rule.ruleId, this.rule.name));
                        });
                    }
                });

                return Promise.all(resolves).then(() => {
                    this.currentPage = 0;
                    this.timer = 0;
                    this.pages = [];
                    this.results.clear();
                });
            }
            else {
                let field = this.rule.cf || "content";
                let content = "";
                let result: ExtractResult = Array.from(this.results.values()).first();

                this.results.forEach(r => {
                    content += r.metas[field];
                });

                result.metas[field] = content;

                return db.article.update(result.metas, this.rule.ruleId, this.rule.name).then(() => {
                    this.currentPage = 0;
                    this.timer = 0;
                    this.pages = [];
                    this.results.clear();
                });
            }
        }
    }
}

export const autoPaging = new AutoPaging();